package spring.cloud.tasks.executor.executor.task.execute_runtime_context;


import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import spring.cloud.tasks.common.Symbols;
import spring.cloud.tasks.common.status.RenewalStatus;
import spring.cloud.tasks.executor.executor.task.task_item_execute.Status;
import spring.cloud.tasks.executor.executor.task.task_item_execute.TaskItemExecute;

import java.util.Date;
import java.util.UUID;


@Slf4j
@Setter
@Getter
public class TaskItemExecuteRuntimeContext {
    public boolean isReported = false;//是否汇报执行信息
    //
    public volatile boolean needStop = false;//外部指令
    public volatile String needStopMessage;
    //
    public String nameSpace;
    public String executorId;
    public String taskId;
    public String taskInstanceId;
    public String taskStage;
    public String taskStage$type;
    public int taskStage$type$index;
    //
    String taskDataRangeRule;
    String taskItemInfo;
    //
    String taskProperties;
    String taskInstanceProperties;
    String taskItemIndexProperties;
    //
    private Date nextFireDate;//指的是可以触发的时间
    private Date timeoutDateTime;//超时时间(任务管理页面设置-init5分钟)
    private Date lockDateTime;//锁时间(任务管理页面设置-init5)
    public Long allowDeleteTaskItemExecuteRuntimeContextTimeStamp;//
    //
    String renewalStatus = RenewalStatus.INIT;//续期状态。续期成功才允许执行。
    public boolean isNeedReRenewalAtNextExecutePeriod = false;//是否需要下次执行的时候再重试续期。
    public String renewalExceptionMessage = "";
    //
    public volatile Date lastReportDate = new Date();
    //
    String taskStageStatus;//任务阶段状态
    String taskItemStatus;//任务阶段分片执行状态

    public static String getTaskItemId(
            String taskId,//
            String taskInstanceId,//
            String taskStage,//
            String taskStage$type,//
            Integer taskStage$type$index) {//
        return Symbols.SLASH + taskId + Symbols.SLASH + taskInstanceId + Symbols.SLASH + taskStage + Symbols.SLASH + taskStage$type + Symbols.SLASH + taskStage$type$index;
    }

    public static String getTaskItemId(TaskItemExecute taskItemExecutet) {//
        return Symbols.SLASH + taskItemExecutet.taskId + Symbols.SLASH + taskItemExecutet.taskInstanceId + Symbols.SLASH + taskItemExecutet.taskStage + Symbols.SLASH + taskItemExecutet.taskStage$type + Symbols.SLASH + taskItemExecutet.taskStage$type$index;
    }

    //
    private boolean registered = false;//是否注册成功
    //
    private String threadName;
    private boolean createdThread = false;
    private Thread.State threadState;

    private Long beginTime;
    private Long completeTime;
    //
    //任务项续期信息
    private int maxAllowRunningTimeMinutes;
    private Long maxAllowRunningTime;//任务执行最大允许的执行时间(对内如果没有进行续期则程序需要终止)
    private Long maxRenewalTime;//max允许续期的时间
    //线程监控信息
    private Long lastTaskMonitorThreadReportTime;
    //任务自身信息
    private Long lastTaskSelfReportTime;
    //执行状态信息
    private int status = Status.RUNNING;
    private String message = "";

    public TaskItemExecuteRuntimeContext(
            String nameSpace, //
            String executorId, //
            String taskId, //
            String taskInstanceId,//
            String taskStage,//
            String taskStageType, //
            Integer taskItemIndex, //
            Date nextFireDate,//
            Date timeoutDateTime,//
            Date lockDateTime,//
            int maxAllowRunningTimeMinutes) {
        this.nameSpace = nameSpace;
        this.executorId = executorId;
        this.taskId = taskId;
        this.taskInstanceId = taskInstanceId;
        this.taskStage = taskStage;
        this.taskStage$type = taskStageType;
        this.taskStage$type$index = taskItemIndex;
        //
        this.nextFireDate = nextFireDate;
        this.timeoutDateTime = timeoutDateTime;
        this.lockDateTime = lockDateTime;
        this.allowDeleteTaskItemExecuteRuntimeContextTimeStamp = lockDateTime.getTime() + 10 * 1000L * 60;//十分钟后进行清理。（终止状态即可修改该值为最新的清理时间点）
        //
        this.maxAllowRunningTimeMinutes = maxAllowRunningTimeMinutes;
    }

    public final String createThreadName() {
        String threadName = "task-item-execute:" + nameSpace + "/" + executorId + "/" + taskId + "/" + taskInstanceId + "/" + taskStage$type$index + "/" + UUID.randomUUID();
        return threadName;
    }

    public void run() {
        //在真正运行的时候才进行实时信息处理。任务上下文，在进行初始化的时候，只是把配置信息，记录下来。
        this.threadState = Thread.State.NEW;
        this.beginTime = System.currentTimeMillis();
        //任务项续期信息
        this.maxAllowRunningTime = beginTime + maxAllowRunningTimeMinutes * 1000L * 60;
        this.maxRenewalTime = this.maxAllowRunningTime + 1L * 1000L * 60;//间隔1分钟。Redission是每隔10秒续期一次30秒。
        //
        //任务自身信息
        this.lastTaskSelfReportTime = beginTime;
        //线程监控信息
        this.lastTaskMonitorThreadReportTime = beginTime;
    }

    public RenewalTimeInfo calculateNewRenewalInfo() {
        long beginTime = System.currentTimeMillis();
        //任务项续期信息
        long maxAllowRunningTime = beginTime + maxAllowRunningTimeMinutes * 1000L * 60;
        long maxRenewalTime = this.maxAllowRunningTime + 1L * 1000L * 60;
        RenewalTimeInfo renewalTimeInfo = new RenewalTimeInfo();
        renewalTimeInfo.beginTime = beginTime;
        renewalTimeInfo.maxAllowRunningTime = maxAllowRunningTime;
        renewalTimeInfo.maxRenewalTime = maxRenewalTime;
        return renewalTimeInfo;
    }

    public static class RenewalTimeInfo {
        public long beginTime;
        //任务项续期信息
        public long maxAllowRunningTime;
        public long maxRenewalTime;
    }

    public boolean isFinished() {
        return Status.RUNNING != status;//只要不是运行都表示任务结束了
    }

    public void statusCalculate() {
        if (status != Status.RUNNING) {
            return;
        } else {

        }

    }
}
